#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time     : 2020/6/12 16:03
# @Author   : Dremeue

import time
import csv
import sys
import warnings
from tinyutils.adb.adb_utils import AdbUtils
from tinyutils.time.time_utils import TimeUtils
from tinyutils.config.config_utils import ConfigUtils
from tinyutils.echarts.echarts_utils import EchartsUtils
from tinyutils.csv.csv_utils import CsvUtils

# 不打印pyecharts的警告
warnings.filterwarnings("ignore", module="pyecharts")


def get_sections_list(config_file):
    """
    获取配置文件的sections_list

    :param config_file:
    :return:
    """
    config = ConfigUtils(config_file)

    # 获取所有的section
    sections_list = config.get_sections()

    # 获取过滤词
    filter_word = config.get_value_by_section_and_option('setting', 'filter_word')

    # 过滤只包含过滤词的section
    sections_list = filter(lambda section_name: section_name.find(filter_word) != -1, sections_list)

    return config, sections_list


def get_package_and_activity(config, section):
    """
    获取要测试的应用包名和activity名

    :param config: 配置文件对象
    :param section: section名
    :return:
    """
    package, actiity = config.get_options_by_section(section)

    # 获取到package名
    package_name = config.get_value_by_section_and_option(section, package)

    # 获取到activity名
    activity_name = config.get_value_by_section_and_option(section, actiity)

    return package_name, activity_name


def get_launch_time(content):
    """
    获取启动时间

    :param content:
    :return:
    """

    # 与获取到的时间格式保持一致, 避免报错
    start_time = "-1\n"

    for line in content.readlines():
        if "TotalTime" in line:
            start_time = line.split(":")[1]
            content.close()
            break
    return start_time


def write_result_to_csv(section, mode, data):
    """
    把结果写入到report文件夹下的, csv文件里面

    :param section:
    :param mode:
    :param data:
    :return:
    """

    # 生成带有当前时间的csv文件
    csv_file = "./report/{}_{}_{}.csv".format(section, mode, TimeUtils.get_current_time(is_strip=True))

    csvUtils = CsvUtils(csv_file)

    header_list = ("launch_time",)
    data_list = []
    # data传过来的是一个列表, 需要把每一个元素转成元组的形式, 否则写出的数据会有问题
    # data传过来的形式:  data = [' 49101\n', ' 774\n', ' 935\n', ' 419\n', ' 349\n']
    data = list(map(lambda item: int(item.strip().replace('\n', '')), data))
    for item in data:
        data_list.append((item,))

    csvUtils.write_data(header_list, data_list)


def run_one_time(package_name, activity_name, delay_time, mode='hot'):
    time.sleep(delay_time)

    # 启动activity
    content = AdbUtils.start_app(package_name, activity_name)

    # 获取启动时间, 并保存到列表里
    start_time = get_launch_time(content)

    # 退出应用
    if mode == 'cold':
        AdbUtils.kill_app(package_name)
    elif mode == 'hot':
        AdbUtils.back()
    time.sleep(delay_time)

    # 返回启动时间
    return start_time


def run_times_and_get_charts(times, package_name, activity_name, launcher_time_list, section, delay_time, mode='hot'):
    """
    运行并得到数据

    :param times: 运行次数
    :param package_name: 包名
    :param activity_name: activity名
    :param launcher_time_list: 保存启动时间的列表
    :param section: 读取的section名
    :param delay_tme: 每次启动前/关闭后的等待时间, 从配置文件中获取
    :param mode: 启动模式, 'cold'代表冷启动, 'hot代表热启动'
    :return:
    """
    # 获取到应用的启动时间, 传入到列表里
    for i in range(times):
        start_time = run_one_time(package_name, activity_name, delay_time=delay_time, mode=mode)
        launcher_time_list.append(start_time)

    # 注释掉打印
    # print("{}-{}启动数据: ".format(package_name, mode), launcher_time_list)

    # 把结果写到csv文件中
    write_result_to_csv(section, mode, launcher_time_list)

    # 生成启动图表
    EchartsUtils.get_basic_line([i for i in range(0, times)], [package_name], [launcher_time_list],
                                line_title=package_name, html_name="./report/{}_{}_{}.html"
                                .format(section, mode, TimeUtils.get_current_time(is_strip=True)))


def main(config_file="./config/launch_time.ini"):
    # 获取到配置文件和section列表
    config, sections_list = get_sections_list(config_file)

    mode = config.get_value_by_section_and_option('setting', 'mode')

    # 取出每一个应用
    for section in sections_list:

        # 保存启动时间的列表
        cold_launcher_time_list = []
        hot_launcher_time_list = []

        # 获取包名和activity名
        package_name, activity_name = get_package_and_activity(config, section)

        # 获取运行次数
        times = int(config.get_value_by_section_and_option('setting', 'times'))
        delay_time = int(config.get_value_by_section_and_option('setting', 'delay_time'))

        if mode == 'cold':
            # 执行冷启动并得到图表
            run_times_and_get_charts(times, package_name, activity_name, cold_launcher_time_list, section,
                                     delay_time=delay_time, mode='cold')
        elif mode == 'hot':
            # 执行热启动并得到图表
            run_times_and_get_charts(times, package_name, activity_name, hot_launcher_time_list, section,
                                     delay_time=delay_time, mode='hot')
        elif mode == 'all':
            # 执行冷热启动,并得到图表
            run_times_and_get_charts(times, package_name, activity_name, cold_launcher_time_list, section,
                                     delay_time=delay_time, mode='cold')
            run_times_and_get_charts(times, package_name, activity_name, hot_launcher_time_list, section,
                                     delay_time=delay_time, mode='hot')


if __name__ == '__main__':
    main()
